<?php

namespace Chaosyeo\SolarEngine;

use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

class RestfulClient
{
    const DEFAULT_HOST          = 'https://api-receiver.detailroi.com';
    const DEFAULT_OVERSEA_HOST  = 'https://vg-api-receiver.detailroi.com';
    const DEFAULT_URI           = '/datareceiver/receive/v3/sapi';
    const DEFAULT_TIMEOUT       = 5;

    private $key;
    private $uri;
    private $host;
    private $timeout;

    public function __construct(string $key = '', array $options = [])
    {
        $this->key     = $key;
        $this->host    = $options['host'] ?? self::DEFAULT_HOST;
        $this->uri     = $options['uri'] ?? self::DEFAULT_URI;
        $this->timeout = $options['timeout'] ?? self::DEFAULT_TIMEOUT;

        if ($this->timeout <= 0) {
            throw new Exception('Timeout must be greater than 0');
        }
    }

    protected function request(string $uri, string $method = 'GET', array $query = [], array $data = []): array
    {
        $client = new Client([
            'base_uri' => $this->host,
            'timeout'  => $this->timeout
        ]);

        $options = ['query' => $query];

        if ($method == 'POST') {
            $options['json'] = $data;
        }

        $response = $client->request($method, $uri, $options);
        if ($response->getStatusCode() != 200) {
            throw new Exception('SolarEngine S2S API response status code is not 200');
        }
        $content = json_decode($response->getBody()->getContents(), true);

        if (empty($content) || !is_array($content)) {
            throw new Exception('Invalid HTTP response');
        }
        return $content;
    }

    public function send(array $events): bool
    {
        $ts = intval(microtime(true) * 1000);

        array_walk($events, function ($value, $key) use (&$events, $ts) {
            $content            = $value->toArray();
            $content['_appkey'] = $this->key;
            $content['_ts']     = $ts;
            $events[$key]       = $content;
        });

        $this->request($this->uri, 'POST', [
            'timestamp' => $ts,
            'sign'      => md5($this->key . $ts)
        ], $events);

        return true;
    }
}
